package cn.xorange.commons.data.dao;

import cn.hutool.core.util.ReflectUtil;
import cn.xorange.commons.data.build.BaseBuild;
import cn.xorange.commons.data.build.TableBuild;
import cn.xorange.commons.data.constants.FieldConstants;
import cn.xorange.commons.data.core.entity.BaseEntity;
import cn.xorange.commons.data.entity.MyBatisParam;
import cn.xorange.commons.data.utils.DataUtil;
import cn.xorange.commons.data.utils.ParamUtil;
import cn.xorange.commons.datasource.constants.DriverType;
import cn.xorange.commons.utils.lang.ObjectUtils;
import cn.xorange.commons.utils.lang.StringUtils;

import java.lang.reflect.Field;
import java.util.Map;
import java.util.Objects;

/**
 * @author yangjian
 */
public class DaoHelperDao<T extends BaseEntity>  extends BaseBuild<T> {


    public String getEntity(T t){
        boolean isLogicDel = TableBuild.isLogicDel(t.getClass());
        super.whereBuild.initWhere(t,isLogicDel);
        columnBuild.getSelectColumn(t, TableBuild.isLogicDel(t.getClass()));
        StringBuffer sb = new StringBuffer();
        sb.append("select ");
        sb.append(columnBuild.getColSql());
        sb.append(" from ");
        sb.append(TableBuild.getName(t,super.getDsType(),super.isMapUnderscoreToCamelCase() ));
        sb.append(super.whereBuild.getWhereSql());
        t.p = new MyBatisParam();
        t.p.setSql(sb.toString());
        t.p.setWhere(super.whereBuild.getWhereParamMap());
        return t.p.getSql();
    }

    public String getEntityById(Object id, Class<T> tClass){
        Field keyField = ParamUtil.getKeyField(tClass);
        String keyCol = ParamUtil.getColName(keyField,super.isMapUnderscoreToCamelCase());
        T newT = ReflectUtil.newInstance(tClass);
        StringBuffer sb = new StringBuffer();
        sb.append("select  * from ");
        sb.append(TableBuild.getName(newT,super.getDsType(),super.isMapUnderscoreToCamelCase() ));
        sb.append(" where ");
        sb.append(keyCol);
        sb.append("= #{param1}");
        return sb.toString();
    }

    public String getCount(T t){
        boolean isLogicDel = TableBuild.isLogicDel(t.getClass());
        super.whereBuild.initWhere(t,isLogicDel);
        StringBuffer sb = new StringBuffer();
        sb.append("select count(*) from ");
        sb.append(TableBuild.getName(t, super.getDsType(),super.isMapUnderscoreToCamelCase()));
        sb.append(this.whereBuild.getWhereSql());
        t.p = new MyBatisParam();
        t.p.setSql(sb.toString());
        t.p.setWhere(this.whereBuild.getWhereParamMap());
        return t.p.getSql();
    }


    public String getPTree(Map map){
        StringBuffer sb = new StringBuffer();
        sb.append("select * from ");
        sb.append(map.get("param1"));
        sb.append(" where ");
        sb.append(map.get("param2"));
        sb.append(" = #{param3}");
        return sb.toString();
    }

    public String updateOtherTreeNode(Map map){
        StringBuffer sb = new StringBuffer();
        sb.append("update ${tableName} ");
        sb.append(StringUtils.format("set tree_node = concat(#{newNode},substr(tree_node,length(concat(#{oldNode},'{}')))) ", FieldConstants.TREE_SEPARATOR));
        sb.append("where tree_node like concat(#{oldNode,jdbcType=VARCHAR},'%')");
        return sb.toString();
    }


    public String getTableColumn(Map map){
        String dbType = ObjectUtils.toString(map.get("dbType"));
        String tableName = ObjectUtils.toString(map.get("tableName"));
        String sql = null;
        if(StringUtils.equals(dbType, DriverType.ORACLE)){
            String[] tableNames = tableName.split("\\.");
            if (tableNames.length>1){
                sql = StringUtils.format("select distinct column_name,data_type,data_length as length from all_tab_columns where owner = '{}' and table_name = '{}'",tableNames[0].toUpperCase(),tableNames[1].toUpperCase());
            }else {
                sql = StringUtils.format("select distinct column_name,data_type,data_length as length from all_tab_columns where table_name = '{}'",tableName);
            }
        }else {
            sql = StringUtils.format("select distinct column_name,data_type,character_maximum_length as length from information_schema.columns where table_name='{}'",tableName.toLowerCase());
        }
        return sql;
    }


}
